package com.gitee.xzb617.mybatis.query.util;

import com.gitee.xzb617.mybatis.query.condition.DateCondition;
import com.gitee.xzb617.mybatis.query.condition.QueryCondition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.util.Map;
import java.util.Set;

/**
 * sql工具
 * @author: XuZhibin
 * @date: 2023/12/29 14:05
 * @version: v1.0
 * @attention:
 */
public class SqlUtil {

    private final static Logger LOG = LoggerFactory.getLogger(SqlUtil.class);

    /**
     * 生成完整的SQL语句
     * @param tableName 表名
     * @param columns 列名数组
     * @param queryCondition 条件
     * @return
     */
    public static String generateFullSql(String tableName, String[] columns, QueryCondition queryCondition, String dbType) {
        // 拼接字段sql
        String columnSql = "";
        if (columns.length > 0) {
            columnSql = " " + String.join(",", columns) +" ";
        } else {
            columnSql = " * ";
        }
        // 拼接查询条件
        StringBuffer buffer = new StringBuffer();
        Map<String, Object> conditions = queryCondition.getCommonConditionMap();
        if (conditions != null) {
            Set<Map.Entry<String, Object>> entries = conditions.entrySet();
            for (Map.Entry<String, Object> entry : entries) {
                String colName = entry.getKey();
                Object colValue = entry.getValue();
                if (colValue != null) {
                    Class<?> aClass = colValue.getClass();
                    if (aClass.isAssignableFrom(String.class) || aClass.isAssignableFrom(Character.class)) {
                        String cv = "'" + colValue + "'";
                        buffer.append(" and ").append(colName).append("=").append(cv);
                    } else {
                        buffer.append(" and ").append(colName).append("=").append(colValue);
                    }
                } else {
                    buffer.append(" and ").append(colName).append(" is null");
                }
            }
        }
        // 解析时间条件
        Map<String, DateCondition> dateConditionMap = queryCondition.getDateConditionMap();
        if (dateConditionMap != null) {
            Set<Map.Entry<String, DateCondition>> entries = dateConditionMap.entrySet();
            for (Map.Entry<String, DateCondition> entry : entries) {
                String colName = entry.getKey();
                DateCondition dateCondition = entry.getValue();

                Object colValue = dateCondition.getColumnValue();
                if (colValue != null) {
                    // 根据不同数据库 匹配日期格式
                    if ("oracle".equals(dbType)) {
//                        colValue = "to_date('" + colValue + "', '" + dateCondition.getDateFormat() + "')";
                        colValue = "to_timestamp('" + colValue + "', '" + dateCondition.getDateFormat() + "')";
                    }
                    else if ("mysql".equals(dbType)) {
                        colValue = "STR_TO_DATE('" + colValue + "', '" + dateCondition.getDateFormat() + "')";
                    }
                    buffer.append(" and ").append(colName).append("=").append(colValue);
                } else {
                    buffer.append(" and ").append(colName).append(" is null");
                }
            }
        }
        // 去掉多余的 and
        String var1 = buffer.toString();
        if (var1.startsWith(" and")) {
            var1 = var1.substring(4);
        }
        String conditionSql = "";
        if (var1.length() > 0) {
            conditionSql = "where " + var1;
        }
        // 拼接最终sql
        String fullSql = "select" + columnSql  + " from " + tableName  + " " + conditionSql;
        if (LOG.isInfoEnabled()) {
            LOG.info("查询SQL: " + fullSql);
        }
        return fullSql;
    }


    /**
     * 获取数据库类型
     * @param dataSource 数据源
     * @return
     */
    public static String getDbType(DataSource dataSource) {
        try {
            Connection connection = dataSource.getConnection();
            DatabaseMetaData metaData = connection.getMetaData();
            String databaseProductName = metaData.getDatabaseProductName();
            if (("MySQL").equals(databaseProductName)) {
                return "mysql";
            } else if(("Oracle").equals(databaseProductName)) {
                return "oracle";
			} else {
                return databaseProductName;
            }
        } catch (Exception e) {
            throw new IllegalStateException("获取当前数据的数据库类型失败，原因：" + e.getMessage(), e);
        }
    }
}
